package com.jack.lib.net

import com.jack.lib.net.cache.Cache
import com.jack.lib.net.loading.Loading
import com.jack.lib.core.ext.toastW
import com.jack.lib.core.net.*
import io.reactivex.Observable
import kotlinx.coroutines.Job


/**
 * author : jack(黄冲)
 * e-mail : 907755845@qq.com
 * create : 2020/7/29
 * desc   :
 */
class JNetParam<T, J: JBaseData<T>>(var view: JNetView) {
    lateinit var loading: Loading
    lateinit var cache: Cache
    lateinit var dispatchMode: NetDispatchMode
    lateinit var ktApi: (suspend () -> J)
    lateinit var result: NetResult<T, J>
    var networkChangeAutoRetry: Boolean = true
    var onNext: ((T?) -> Unit) = { }
    var onFail: ((J) -> Unit) = { }
    var onError: ((cause: Throwable) -> Unit) = { }
    var onComplete: (() -> Unit) = { }
    var onCancel: (() -> Unit) = { }
    var catchError: Boolean = true
    var job: Job? = null

    fun getParam(): IParam<T, J> = ParamImpl(this)

    companion object{
        inline fun <T, J: JBaseData<T>> build(block: Builder<T, J>.() -> Unit): JNetParam<T, J> {
            return Builder<T, J>().apply(block).build()
        }

        inline fun <T, J: JBaseData<T>> create(block: Builder<T, J>.() -> Unit): Builder<T, J> {
            return Builder<T, J>().apply(block)
        }
    }
}

class Builder<T, J: JBaseData<T>>{

    lateinit var view: JNetView

    var dispatchMode = NetDispatchMode.NORMAL

    var loadingMode = NetLoadingMode.DELAY

    var networkChangeAutoRetry = true

    var strategy: NetCacheStrategy = NetCacheStrategy.NOT()

    var onNext: ((T?) -> Unit) = { }

    lateinit var ktApi: (suspend () -> J)

    var onFail: ((J) -> Unit) = { }

    var onError: ((cause: Throwable) -> Unit) = { }

    var onComplete: (() -> Unit) = { }

    fun build(): JNetParam<T, J> {
       return JNetParam<T, J>(view).also {
            it.onNext = onNext
            it.onFail = onFail
            it.onError = onError
            it.onComplete = onComplete
            it.dispatchMode = dispatchMode
            it.loading = Loading.obtain(loadingMode, view)
            it.networkChangeAutoRetry = networkChangeAutoRetry
            it.cache = Cache.obtain(strategy, ktApi.hashCode())
            it.ktApi = ktApi
        }
    }
}
